package dawnland03.model.action.impl;

import dawnland03.model.action.Action;
import dawnland03.model.action.parameter.ActionInputParam;
import dawnland03.model.action.handler.ActionHandler;
import dawnland03.model.entity.Entity;
import dawnland03.model.entity.attribute.PhysicalAttribute;
import dawnland03.model.item.ItemType;

import java.util.Map;
import java.util.HashMap;

/**
 * User: Petru Obreja (obrejap@yahoo.com)
 * Date: Jan 18, 2010
 * Time: 10:36:13 PM
 */
public class ActionFactory {
    private static ActionHandler actionHandler = new ActionHandler();

    public static Action createInitAction(Entity owner) {
        return new InitAction(owner, 0, actionHandler);
    }

    public static Action createGatherCoalAction(Entity owner) {
        Map<ActionInputParam, Object> actionParams = new HashMap<ActionInputParam, Object>();
        actionParams.put(ActionInputParam.ITEM_TYPE, ItemType.COAL);
        Map<PhysicalAttribute, Integer> physicalAttributeRequirements = new HashMap<PhysicalAttribute, Integer>();
        physicalAttributeRequirements.put(PhysicalAttribute.STRENGTH, 1);
        physicalAttributeRequirements.put(PhysicalAttribute.DEXTERITY, 1);
        Map<PhysicalAttribute, Double> physicalAttributeMultipliers = new HashMap<PhysicalAttribute, Double>();
        physicalAttributeMultipliers.put(PhysicalAttribute.STRENGTH, 1.0);
        physicalAttributeMultipliers.put(PhysicalAttribute.DEXTERITY, 1.0);
        return new GatherAction(owner, actionParams, physicalAttributeRequirements, physicalAttributeMultipliers, 1, actionHandler);
    }

    public static Action createGatherWoodAction(Entity owner) {
        Map<ActionInputParam, Object> actionParams = new HashMap<ActionInputParam, Object>();
        actionParams.put(ActionInputParam.ITEM_TYPE, ItemType.WOOD);
        Map<PhysicalAttribute, Integer> physicalAttributeRequirements = new HashMap<PhysicalAttribute, Integer>();
        physicalAttributeRequirements.put(PhysicalAttribute.STRENGTH, 1);
        physicalAttributeRequirements.put(PhysicalAttribute.DEXTERITY, 1);
        Map<PhysicalAttribute, Double> physicalAttributeMultipliers = new HashMap<PhysicalAttribute, Double>();
        physicalAttributeMultipliers.put(PhysicalAttribute.STRENGTH, 1.0);
        physicalAttributeMultipliers.put(PhysicalAttribute.DEXTERITY, 1.0);
        return new GatherAction(owner, actionParams, physicalAttributeRequirements, physicalAttributeMultipliers, 1, actionHandler);
    }

    public static Action createMoveAction(Entity owner, Integer destinationMatrixCellId, Long duration) {
        Map<ActionInputParam, Object> actionParams = new HashMap<ActionInputParam, Object>();
        actionParams.put(ActionInputParam.DESTINATION, destinationMatrixCellId);
        Map<PhysicalAttribute, Integer> physicalAttributeRequirements = new HashMap<PhysicalAttribute, Integer>();
        Map<PhysicalAttribute, Double> physicalAttributeMultipliers = new HashMap<PhysicalAttribute, Double>();
        return new MoveAction(owner, actionParams, physicalAttributeRequirements, physicalAttributeMultipliers, duration, actionHandler);
    }

    public static Action createAcquireLockAction(Entity owner, Integer destinationMatrixCellId, long timeout) {
        Map<ActionInputParam, Object> actionParams = new HashMap<ActionInputParam, Object>();
        actionParams.put(ActionInputParam.DESTINATION, destinationMatrixCellId);
        actionParams.put(ActionInputParam.TIMEOUT, timeout);
        Map<PhysicalAttribute, Integer> physicalAttributeRequirements = new HashMap<PhysicalAttribute, Integer>();
        Map<PhysicalAttribute, Double> physicalAttributeMultipliers = new HashMap<PhysicalAttribute, Double>();
        return new AcquireLockAction(owner, actionParams, physicalAttributeRequirements, physicalAttributeMultipliers, 0, actionHandler);
    }

    public static Action createReleaseLockAction(Entity owner, Integer destinationMatrixCellId) {
        Map<ActionInputParam, Object> actionParams = new HashMap<ActionInputParam, Object>();
        actionParams.put(ActionInputParam.DESTINATION, destinationMatrixCellId);
        Map<PhysicalAttribute, Integer> physicalAttributeRequirements = new HashMap<PhysicalAttribute, Integer>();
        Map<PhysicalAttribute, Double> physicalAttributeMultipliers = new HashMap<PhysicalAttribute, Double>();
        return new ReleaseLockAction(owner, actionParams, physicalAttributeRequirements, physicalAttributeMultipliers, 0, actionHandler);
    }

    public static Action duplicate(Action action) {
        switch (action.getActionType()) {
            case GATHER:
                ItemType itemType = (ItemType) action.getInputParam(ActionInputParam.ITEM_TYPE);
                if (itemType == ItemType.COAL) {
                    return createGatherCoalAction(action.getOwner());
                } else {
                    return createGatherWoodAction(action.getOwner());
                }
            case MOVE:
                Integer destinationMatrixCellId = (Integer) action.getInputParam(ActionInputParam.DESTINATION);
                return createMoveAction(action.getOwner(), destinationMatrixCellId, action.getDuration());
            case ACQUIRE_LOCK:
                destinationMatrixCellId = (Integer) action.getInputParam(ActionInputParam.DESTINATION);
                long timeout = (Long) action.getInputParam(ActionInputParam.TIMEOUT);
                return createAcquireLockAction(action.getOwner(), destinationMatrixCellId, action.getDuration());
            default:
                throw new IllegalStateException("unhandled " + action.getActionType() + " for duplicate");
        }
    }
}
